<!DOCTYPE html>
<html>

<head>
    <title>extrudepolyogn china</title>
    <script type="text/javascript" src="https://unpkg.com/randomcolor@0.6.2/randomColor.js"></script>
    <script type="text/javascript" src="https://unpkg.com/dat.gui@0.7.6/build/dat.gui.min.js"></script>
    <link type="text/css" rel="stylesheet" href="https://unpkg.com/maptalks/dist/maptalks.css">
    <script type="text/javascript" src="https://unpkg.com/maptalks/dist/maptalks.js"></script>
    <script type="text/javascript" src="https://unpkg.com/@maptalks/gl/dist/maptalksgl.js"></script>
    <script type="text/javascript" src="https://unpkg.com/three@0.138.0/build/three.min.js"></script>
    <script type="text/javascript" src="https://unpkg.com/maptalks.three@latest/dist/maptalks.three.js"></script>
    <style>
        html,
        body {
            margin: 0px;
            height: 100%;
            width: 100%;
        }

        #map {
            width: 100%;
            height: 100%;
            background-color: #000;
        }
    </style>
</head>

<body>
    <div id="map"></div>
    <script>

        const eventDispatch = {
            layers: [],
            _sortLayers: function () {
                this.layers = this.layers.sort((d1, d2) => {
                    return d2.zindex - d1.zindex;
                });
            },
            addLayer: function (layer, zindex = 0) {
                if (this.layers.filter(d => {
                    return d.layer === layer;
                }).length > 0) {
                    return;
                }
                this.layers.push({
                    layer,
                    zindex,
                    click: false
                });
                this._sortLayers();
            },
            removeLayer: function (layer) {
                //   todo
            },
            test: function (target) {
                if (!target || !target.getLayer) {
                    console.error('not find target layer');
                    return;
                }
                const layer = target.getLayer();
                const layers = this.layers.filter(d => {
                    return d.layer === layer;
                });
                if (layers.length === 0) {
                    console.error('not find layer from eventDispatch');
                    return;
                }
                const d = layers[0];
                d.click = true;
                const zindex = d.zindex;
                return new Promise((resolve, reject) => {
                    setTimeout(() => {
                        let isClick = false;
                        this.layers.forEach(d => {
                            if (d.zindex > zindex && d.click) {
                                isClick = true;
                            }
                        });
                        if (isClick) {
                            // console.warn('high zindex layers is clicked', target);
                            return;
                        }
                        this.layers.forEach(d => {
                            if (d.layer === layer) {
                                d.click = false;
                            }
                        })
                        resolve();
                    }, zindex * 16);
                })
            }

        }

        var map = new maptalks.Map("map", {
            "center": [108.70296180227058, 32.44563434720479], "zoom": 5.717254596370028, "pitch": 58.40000000000007, "bearing": 0.8533528124999066,

            centerCross: true,
            doubleClickZoom: false,
            baseLayer: new maptalks.TileLayer('tile', {
                urlTemplate: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
                subdomains: ['a', 'b', 'c', 'd'],
                attribution: '&copy; <a href="http://osm.org">OpenStreetMap</a> contributors, &copy; <a href="https://carto.com/">CARTO</a>'
            })
        });
        // the ThreeLayer to draw buildings
        var threeLayer = new maptalks.ThreeLayer('t', {
            forceRenderOnMoving: true,
            forceRenderOnRotating: true,
            identifyCountOnEvent: 1
            // animation: true
        });

        var meshs = [];
        var material = new THREE.MeshBasicMaterial({ color: '#3e35cf', transparent: true });
        threeLayer.prepareToDraw = function (gl, scene, camera) {
            var light = new THREE.DirectionalLight(0xffffff);
            light.position.set(0, -10, 10).normalize();
            scene.add(light);
            fetch('./data/china.json').then(res => res.json()).then(geojson => {
                const time = 'time';
                console.time(time);
                geojson.features.forEach(f => {
                    const m = material.clone();
                    m.color.setStyle(randomColor());
                    const mesh = threeLayer.toExtrudePolygon(f, {
                        height: f.properties.height || 100000,
                        topColor: '#fff',
                        asynchronous: true
                    }, m);
                    meshs.push(mesh);
                });
                console.timeEnd(time);
                threeLayer.addMesh(meshs);
                meshs.forEach(mesh => {
                    mesh.on('click', e => {
                        eventDispatch.test(e.target).then(() => {
                            console.log('extrudepolygon');
                            console.log(e.target);
                        })
                    })
                });
            })

            threeLayer.config('animation', true);
        };
        eventDispatch.addLayer(threeLayer, 1);

        const sceneConfig = {
            postProcess: {
                enable: true,
                antialias: { enable: true }
            }
        };
        const groupLayer = new maptalks.GroupGLLayer('group', [threeLayer], { sceneConfig });
        groupLayer.addTo(map);

        const layer = new maptalks.VectorLayer('layer').addTo(map);
        const point = new maptalks.Marker(map.getCenter(), {
            symbol: {
                markerType: 'ellipse',
                markerWidth: 100,
                markerHeight: 100
            }
        }).addTo(layer);

        eventDispatch.addLayer(layer, 2);
        point.on('click', e => {
            eventDispatch.test(e.target).then(() => {
                console.log('point');
                console.log(e.target);
            })
        })
        const layer1 = new maptalks.VectorLayer('layer1').addTo(map);
        const point1 = new maptalks.Marker(map.getCenter(), {
            symbol: {
                markerType: 'ellipse',
                markerWidth: 20,
                markerHeight: 20,
                markerFill: "red"
            }
        }).addTo(layer1);

        eventDispatch.addLayer(layer1, 3);
        point1.on('click', e => {
            eventDispatch.test(e.target).then(() => {
                console.log('point1');
                console.log(e.target);
            })
        })


    </script>
</body>

</html>